home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / reuse.lha / reuse / m2c / Memory.c < prev    next >
C/C++ Source or Header  |  1992-08-18  |  6KB  |  180 lines

  1. #include "SYSTEM_.h"
  2.  
  3. #ifndef DEFINITION_General
  4. #include "General.h"
  5. #endif
  6.  
  7. #ifndef DEFINITION_System
  8. #include "System.h"
  9. #endif
  10.  
  11. #ifndef DEFINITION_Memory
  12. #include "Memory.h"
  13. #endif
  14.  
  15. LONGCARD Memory_MemoryUsed;
  16.  
  17. #define MinSizeSmallBlock    4
  18. #define MaxSizeSmallBlock    62
  19. #define MinSizeLargeBlockLog    6
  20. #define MaxSizeLargeBlockLog    24
  21. #define PoolSize    10240
  22. typedef struct S_1 *tBlockPtr;
  23. typedef struct S_1 {
  24.     tBlockPtr Successor;
  25.     LONGINT Size;
  26. } tBlock;
  27. typedef LONGCARD tSmallBlockRange;
  28. typedef LONGCARD tLargeBlockRange;
  29. static struct S_2 {
  30.     ADDRESS A[MaxSizeSmallBlock - MinSizeSmallBlock + 1];
  31. } SmallChain;
  32. static struct S_3 {
  33.     ADDRESS A[MaxSizeLargeBlockLog - MinSizeLargeBlockLog + 1];
  34. } LargeChain;
  35. static ADDRESS PoolFreePtr;
  36. static ADDRESS PoolEndPtr;
  37. static tSmallBlockRange i;
  38. static tLargeBlockRange j;
  39.  
  40.  
  41. ADDRESS Memory_Alloc
  42. # ifdef __STDC__
  43. (LONGINT ByteCount)
  44. # else
  45. (ByteCount)
  46. LONGINT ByteCount;
  47. # endif
  48. {
  49.   tBlockPtr BlockPtr, CurrentBlock, PreviousBlock, BestBlock, PredecessorBlock;
  50.   CARDINAL ChainNumber;
  51.   LONGINT CurrentBlockSize, BestBlockSize;
  52.   tLargeBlockRange j;
  53.  
  54.   ByteCount = (LONGINT)((BITSET)(ByteCount + General_MaxAlign - 1) & General_AlignMasks.A[General_MaxAlign]);
  55.   if (ByteCount <= MaxSizeSmallBlock) {
  56.     if (ByteCount < MinSizeSmallBlock) {
  57.       ByteCount = MinSizeSmallBlock;
  58.     }
  59.     if (SmallChain.A[ByteCount - 4] != NIL) {
  60.       BlockPtr = (tBlockPtr)SmallChain.A[ByteCount - 4];
  61.       SmallChain.A[ByteCount - 4] = (ADDRESS)BlockPtr->Successor;
  62.       return (ADDRESS)BlockPtr;
  63.     } else {
  64.       if ((LONGINT)(PoolEndPtr - (LONGCARD)PoolFreePtr) < ByteCount) {
  65.         if ((LONGCARD)(PoolEndPtr - (LONGCARD)PoolFreePtr) >= MinSizeSmallBlock) {
  66.           Memory_Free((LONGINT)(PoolEndPtr - (LONGCARD)PoolFreePtr), PoolFreePtr);
  67.         }
  68.         PoolFreePtr = Memory_Alloc((LONGINT)PoolSize);
  69.         PoolEndPtr = (ADDRESS)(PoolFreePtr + PoolSize);
  70.       }
  71.       INC1(PoolFreePtr, (LONGCARD)(ADDRESS)ByteCount);
  72.       return PoolFreePtr - (LONGCARD)(ADDRESS)ByteCount;
  73.     }
  74.   } else {
  75.     ChainNumber = General_Log2(ByteCount);
  76.     CurrentBlock = (tBlockPtr)LargeChain.A[ChainNumber - 6];
  77.     PreviousBlock = (tBlockPtr)ADR(LargeChain.A[ChainNumber - 6]);
  78.     BestBlock = NIL;
  79.     BestBlockSize = 1000000000;
  80.     while (CurrentBlock != NIL) {
  81.       CurrentBlockSize = CurrentBlock->Size;
  82.       if (CurrentBlockSize >= ByteCount) {
  83.         if (CurrentBlockSize == ByteCount) {
  84.           PreviousBlock->Successor = CurrentBlock->Successor;
  85.           return (ADDRESS)CurrentBlock;
  86.         }
  87.         if (CurrentBlockSize < BestBlockSize) {
  88.           BestBlock = CurrentBlock;
  89.           BestBlockSize = CurrentBlockSize;
  90.           PredecessorBlock = PreviousBlock;
  91.         }
  92.       }
  93.       PreviousBlock = CurrentBlock;
  94.       CurrentBlock = CurrentBlock->Successor;
  95.     }
  96.     if (BestBlock != NIL) {
  97.       PredecessorBlock->Successor = BestBlock->Successor;
  98.       if (BestBlockSize - ByteCount >= MinSizeSmallBlock) {
  99.         Memory_Free(BestBlockSize - ByteCount, (ADDRESS)BestBlock + (LONGCARD)(ADDRESS)ByteCount);
  100.       }
  101.       return (ADDRESS)BestBlock;
  102.     }
  103.     for (j = ChainNumber + 1; j <= MaxSizeLargeBlockLog; j += 1) {
  104.       CurrentBlock = (tBlockPtr)LargeChain.A[j - 6];
  105.       if (CurrentBlock != NIL) {
  106.         LargeChain.A[j - 6] = (ADDRESS)CurrentBlock->Successor;
  107.         if (CurrentBlock->Size - ByteCount >= MinSizeSmallBlock) {
  108.           Memory_Free(CurrentBlock->Size - ByteCount, (ADDRESS)CurrentBlock + (LONGCARD)(ADDRESS)ByteCount);
  109.         }
  110.         return (ADDRESS)CurrentBlock;
  111.       }
  112.     }
  113.     if (ByteCount < PoolSize) {
  114.       if ((LONGINT)(PoolEndPtr - (LONGCARD)PoolFreePtr) < ByteCount) {
  115.         if ((LONGCARD)(PoolEndPtr - (LONGCARD)PoolFreePtr) >= MinSizeSmallBlock) {
  116.           Memory_Free((LONGINT)(PoolEndPtr - (LONGCARD)PoolFreePtr), PoolFreePtr);
  117.         }
  118.         PoolFreePtr = Memory_Alloc((LONGINT)PoolSize);
  119.         PoolEndPtr = (ADDRESS)(PoolFreePtr + PoolSize);
  120.       }
  121.       INC1(PoolFreePtr, (LONGCARD)(ADDRESS)ByteCount);
  122.       return PoolFreePtr - (LONGCARD)(ADDRESS)ByteCount;
  123.     } else {
  124.       BlockPtr = (tBlockPtr)SysAlloc(ByteCount);
  125.       INC1(Memory_MemoryUsed, ByteCount);
  126.       return (ADDRESS)BlockPtr;
  127.     }
  128.   }
  129. }
  130.  
  131. void Memory_Free
  132. # ifdef __STDC__
  133. (LONGINT ByteCount, ADDRESS a)
  134. # else
  135. (ByteCount, a)
  136. LONGINT ByteCount;
  137. ADDRESS a;
  138. # endif
  139. {
  140.   tBlockPtr BlockPtr;
  141.   tLargeBlockRange ChainNumber;
  142.  
  143.   ByteCount = (LONGINT)((BITSET)(ByteCount + General_MaxAlign - 1) & General_AlignMasks.A[General_MaxAlign]);
  144.   BlockPtr = (tBlockPtr)a;
  145.   if (ByteCount <= MaxSizeSmallBlock) {
  146.     if (ByteCount < MinSizeSmallBlock) {
  147.       ByteCount = MinSizeSmallBlock;
  148.     }
  149.     BlockPtr->Successor = (tBlockPtr)SmallChain.A[ByteCount - 4];
  150.     SmallChain.A[ByteCount - 4] = (ADDRESS)BlockPtr;
  151.   } else {
  152.     ChainNumber = General_Log2(ByteCount);
  153.     BlockPtr->Successor = (tBlockPtr)LargeChain.A[ChainNumber - 6];
  154.     BlockPtr->Size = ByteCount;
  155.     LargeChain.A[ChainNumber - 6] = (ADDRESS)BlockPtr;
  156.   }
  157. }
  158.  
  159. void BEGIN_Memory()
  160. {
  161.   static BOOLEAN has_been_called = FALSE;
  162.  
  163.   if (!has_been_called) {
  164.     has_been_called = TRUE;
  165.  
  166.     BEGIN_General();
  167.     BEGIN_System();
  168.  
  169.     for (i = MinSizeSmallBlock; i <= MaxSizeSmallBlock; i += 2) {
  170.       SmallChain.A[i - 4] = (ADDRESS)NIL;
  171.     }
  172.     for (j = MinSizeLargeBlockLog; j <= MaxSizeLargeBlockLog; j += 1) {
  173.       LargeChain.A[j - 6] = (ADDRESS)NIL;
  174.     }
  175.     PoolFreePtr = (ADDRESS)NIL;
  176.     PoolEndPtr = (ADDRESS)NIL;
  177.     Memory_MemoryUsed = 0;
  178.   }
  179. }
  180.